package com.apimarket.util.kong.impl;

import com.apimarket.entity.kong.Route;
import com.apimarket.factory.JsonMapperFactory;
import com.apimarket.util.UrlUtil;
import com.apimarket.util.kong.KongOperationType;
import com.apimarket.util.kong.KongRoute;
import com.apimarket.util.kong.KongRouteParameters;
import com.apimarket.util.net.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class BaseKongRoute extends KongRoute {
    public BaseKongRoute() {
    }

    public BaseKongRoute(String baseUrl) {
        super(baseUrl);
    }

    @Override
    public Route addRoute(Route route) throws IOException, URISyntaxException {
        //kong对外暴露的添加路由Restful API
        String targetUrl = getBaseUrl() + addPath;
        UrlUtil urlUtil = new UrlUtil(new PostJsonNetContext(targetUrl, getRouteInfoMap(route)));
        JsonNode root = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(root.toString(), Route.class);
    }

    @Override
    public Route addRouteAndJudege(Route route) throws IOException, URISyntaxException {
        //kong对外暴露的添加路由Restful API
        String targetUrl = getBaseUrl() + addPath;
        NewPostJsonNetContext newPostJsonNetContext = new NewPostJsonNetContext(targetUrl, getRouteInfoMap(route));
        //UrlUtil urlUtil = new UrlUtil(new PostJsonNetContext(targetUrl, getRouteInfoMap(route)));
        JsonNode root = newPostJsonNetContext.getResultJsonAndJudge(KongOperationType.ROUTE_ADD);
        return JsonMapperFactory.getInstance().readValue(root.toString(), Route.class);
    }

    @Override
    public List<Route> listAllRoutes() throws IOException, URISyntaxException {
        String targetUrl = getBaseUrl() + listPath;
        return getRoutesList(targetUrl);
    }

    @Override
    public List<Route> listRoutesViaService(String serviceId) throws IOException, URISyntaxException {
        String targetUrl = getBaseUrl() + listViaServicePath + "/" + serviceId + listPath;
        return getRoutesList(targetUrl);
    }

    @Override
    public Route updateRoute(Route route) throws IOException, URISyntaxException {
        String targetUrl = getBaseUrl() + updatePath + "/" + route.getId();
        UrlUtil urlUtil = new UrlUtil(new PatchJsonNetContext(targetUrl, getRouteInfoMap(route)));
        JsonNode root = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(root.toString(), Route.class);
    }

    @Override
    public Route updateRouteAndJudege(Route route,String operationType) throws IOException, URISyntaxException {
        String targetUrl = getBaseUrl() + updatePath + "/" + route.getId();
        NewPatchJsonNetContext newPatchJsonNetContext = new NewPatchJsonNetContext(targetUrl, getRouteInfoMap(route));
        //UrlUtil urlUtil = new UrlUtil(new NewPatchJsonNetContext(targetUrl, getRouteInfoMap(route)));
        JsonNode root = newPatchJsonNetContext.getResultJsonByOperationType(operationType);
        return JsonMapperFactory.getInstance().readValue(root.toString(), Route.class);
    }

    @Override
    public void deleteRoute(String nameOrId) throws IOException, URISyntaxException {
        String targetUrl = getBaseUrl() + deletePath + "/" + nameOrId;
        UrlUtil urlUtil = new UrlUtil(new DeleteNetContext(targetUrl));
        urlUtil.getJsonRoot();
    }

    @Override
    public Route getRouteById(String id) throws IOException, URISyntaxException {
        String targetUrl=getBaseUrl()+listPath+"/"+id;
        UrlUtil urlUtil = new UrlUtil(new GetNetContext(targetUrl, null));
        JsonNode jsonRoot = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(jsonRoot.toString(),Route.class);
    }

    private List<Route> getRoutesList(String targetUrl) throws IOException, URISyntaxException {
        UrlUtil urlUtil = new UrlUtil(new GetNetContext(targetUrl, null));
        JsonNode root = urlUtil.getJsonRoot();
        root = root.get("data");
        if (root == null) return null;
        ObjectMapper mapper = JsonMapperFactory.getInstance();
        CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, Route.class);
        return mapper.readValue(root.toString(), listType);
    }

    //传递参数
    private Map<String, Object> getRouteInfoMap(Route route) {
        Map<String, Object> params = new HashMap<>();
        params.put(KongRouteParameters.ROUTE_ID, route.getId());
        params.put(KongRouteParameters.ROUTE_NAME, route.getName());
        params.put(KongRouteParameters.ROUTE_SERVICE_ID, route.getService());
        params.put(KongRouteParameters.ROUTE_PROTOCOLS, route.getProtocols());
        params.put(KongRouteParameters.ROUTE_METHODS, route.getMethods());
        params.put(KongRouteParameters.ROUTE_HOSTS, route.getHosts());
        params.put(KongRouteParameters.ROUTE_PATHS, route.getPaths());
        params.put(KongRouteParameters.ROUTE_SNIS, route.getSnis());
        params.put(KongRouteParameters.ROUTE_SOURCES, route.getSources());
        params.put(KongRouteParameters.ROUTE_DESTINATIONS, route.getDestinations());
        params.put(KongRouteParameters.ROUTE_REGEX_PRIORITY, route.getRegexPriority());
        params.put(KongRouteParameters.ROUTE_STRIPE_PATH, route.isStripPath());
        params.put(KongRouteParameters.ROUTE_PRESERVE_HOST, route.isPreserveHost());
        params.put(KongRouteParameters.FILTER_TAGS, route.getTags());
        params.put(KongRouteParameters.ROUTE_HTTPS_REDIRECT_STATUS_CODE, route.getHttpsRedirectStatusCode());
        params.put(KongRouteParameters.ROUTE_HEADERS, route.getHeaders());
        params.put(KongRouteParameters.ROUTE_PATH_HANDLING, route.getPathHandling());
        params.entrySet().removeIf(key -> key.getValue() == null);
        return params;
    }
}
